﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Windows.Forms;
using AMM.Business;
using AMM.Business.Business;
using AMM.Business.Project;
using AMM.Business.Store;
using AMM.CustomClassLibrary;
using AMM.CustomWinComponents.Validator;
using AMM.Model;
using AMM.Model.Business;
using AMM.Model.Project;
using AMM.Model.Store;

namespace AMM.UserControls {
    public partial class OutsourceOrderEditControl : BaseEditControl {

        private FlexBindingSource<OutsourceOrder> _fbs;
        private OutsourceQuotationProcessor _outsourceQuotationProcessor;
        private ProduceConductProcessor _produceConductProcessor;
        private List<OutsourceOrderDetail> _oodList;

        public override object BaseEditModel {
            get {
                this._fbs.CurrentItem.OutsourceOrderDetails = this.dgvProduceConductEdit.GetDataSourceEx<OutsourceOrderDetail>();
                return this._fbs.CurrentItem;
            }
            set {
                if (this._fbs == null) { this._fbs = new FlexBindingSource<OutsourceOrder>(); }
                this._fbs.CurrentItem = (OutsourceOrder)value;
            }
        }

        public OutsourceOrderEditControl() {
            this.InitializeComponent();
        }

        private void BindVendor() {
            VendorSearchModel searchModel = new VendorSearchModel() { IsEnabled = true };
            VendorProcessor vendorProcessor = new VendorProcessor(int.MaxValue);
            List<VendorViewModel> vendorList = vendorProcessor.FetchVendorViewModelList(searchModel);

            this.ddlVendor.DisplayMemberEx = "Code";
            this.ddlVendor.ValueMemberEx = "Key";
            this.ddlVendor.HeightEx = 300;
            this.ddlVendor.WidthEx = 400;
            this.ddlVendor.PageSizeEx = 20;
            this.ddlVendor.DataBind(new VendorViewModel(), x => new { x.Code, x.Name, x.Address }, vendorList);
        }

        private void BindProduceConduct(int vendorId) {
            ProductProcessor productProcessor = new ProductProcessor(int.MaxValue);
            List<ProductViewModel> productList = productProcessor.FetchProductViewModelListByVendorId(vendorId);

            ProduceConductSearchModel searchModel = new ProduceConductSearchModel();
            ProduceConductProcessor produceConductProcessor = new ProduceConductProcessor(int.MaxValue);
            List<ProduceConductViewModel> produceConductList = produceConductProcessor.FetchProduceConductViewModelList(searchModel);

            this.ProduceConduct.DisplayMemberEx = "ProduceConductCode";
            this.ProduceConduct.ValueMemberEx = "Key";
            this.ProduceConduct.HeightEx = 300;
            this.ProduceConduct.WidthEx = 400;
            this.ProduceConduct.PageSizeEx = 20;
            this.ProduceConduct.DataBind(new ProduceConductViewModel(), x => new {
                x.ProductCode,
                x.ProduceConductCode,
                x.CustomerOrderCode
            }, produceConductList.Where(x => productList.Any(y => y.Code == x.ProductCode)).ToList());
        }

        private void CreateFormBindings() {
            this._fbs.CreateBinding(this.ddlVendor, x => x.SelectedValueEx, y => y.VendorId);
            this._fbs.CreateBinding(this.tbCode, x => x.Text, y => y.Code, DataSourceUpdateMode.OnPropertyChanged);
        }

        private void BindValidation() {
            this.ValidatorForEdit.SetType(this.ddlVendor, ValidationType.Required);
            this.ValidatorForEdit.SetRequiredMessage(this.ddlVendor, this.RequiredMessage);
        }

        private void BindDataGridView() {
            this.dgvProduceConductEdit.DataSourceEx = this._oodList;
        }

        private void OutsourceEditControl_Load(object sender, EventArgs e) {
            if (this._fbs == null) { this._fbs = new FlexBindingSource<OutsourceOrder>(); }
            this._outsourceQuotationProcessor = new OutsourceQuotationProcessor();
            this._produceConductProcessor = new ProduceConductProcessor();
            this._oodList = this._fbs.CurrentItem.OutsourceOrderDetails.ToList();

            this.BindProduceConduct(this._fbs.CurrentItem.VendorId);
            this.BindVendor();
            this.BindDataGridView();
            this.CreateFormBindings();
            this.BindValidation();

            this.ddlVendor.Enabled = false;
            if (this._fbs.CurrentItem.ClassStatus == ClassStatus.Added) {
                string autoCode = CommonHelper.GenerateAutoCode("PO");
                int maxNumber = new OutsourceOrderProcessor().GetTheMaxFlowNumber(autoCode);
                this._fbs.CurrentItem.Code = CommonHelper.GendrateSpecificCode(autoCode, maxNumber);
                this.ddlVendor.Enabled = true;
            }
        }

        private void ddlVendor_ValueChanged(object sender, EventArgs e) {
            this.BindProduceConduct(Convert.ToInt32(this.ddlVendor.SelectedValueEx));
        }

        private void dgvProduceConductEdit_CellValueChanged(object sender, DataGridViewCellEventArgs e) {
            if (e.RowIndex == -1) { return; }
            int vendorId = Convert.ToInt32(this.ddlVendor.SelectedValueEx);
            OutsourceOrderDetail currentOOD = (OutsourceOrderDetail)this.dgvProduceConductEdit.Rows[e.RowIndex].DataBoundItem;
            ProduceConduct productConduct = this._produceConductProcessor.FetchProduceConductById(currentOOD.ProduceConductId);
            if (productConduct != null) {
                OutsourceQuotation outsourceQuotation = this._outsourceQuotationProcessor.FetchOutsourceQuotationByVendorIdAndProductId(vendorId, productConduct.ProductId);
                if (outsourceQuotation == null) {
                    this.ShowError("未找到对应的报价单，或者是报价单未通过审核");
                    return;
                }
                currentOOD.Price = outsourceQuotation.IsMultiple
                    ? currentOOD.Quantity > outsourceQuotation.PriceThresholdValue ? outsourceQuotation.PriceGreaterThan : outsourceQuotation.Price
                    : outsourceQuotation.Price;
                currentOOD.Total = currentOOD.Quantity * currentOOD.Price;
                currentOOD.DeliveryDate = DateTime.Now.AddDays(outsourceQuotation.PreProcurementCycle + outsourceQuotation.ProcurementCycle);
            }
            this._oodList[e.RowIndex] = currentOOD;
            this.BindDataGridView();
        }
    }
}
